<script>
export default {
  props: ['opts'],
  data() {
    return {
      isPlay: false, // 视频是否在播放
      ismute: false, // 是否静音
      muteStatus: '',
      videoOpts: {
        curTime: '00:00', // 当前播放时间
        totalTime: '00:00', // 总的时长
        progress: '0%', // 进度条进度百分比
        vol_progress: {
          scrollTop: 0, // 音量进度条到页面顶部的距离
        },
        volume: '100', // 音量百分比
        isFullScreen: false, // 是否全屏
      },
      isError: false,
      isShowFooter: true, // 是否隐藏控制条
      isShowVolume: false, // 是否隐藏音量控制条
      left_padding: 0,
    }
  },
  mounted() {
    this.left_padding = this.$refs.myProgress.getBoundingClientRect().left
  },
  methods: {
    // -------- 工具方法 --------
    /**
     * 格式化时间
     * @param  {[Number]} n 时间长短
     * @return {[String]}   格式化的时间 'xx:xx:xx'
     */
    formatTime(n) {
      const minute = Math.floor(n / 60)
      const second = n % 60
      const func = (num) => {
        return num > 9 ? num : '0' + num
      }
      return minute < 60 ? `${func(minute)}:${func(second)}`:`${func(Math.floor(minute / 60))}:${func(minute)}:${func(second)}`
    },
    /* -------  -------- */
    /**
     * 更改视频状态和按钮样式
     */
    togglePlayStatus() {
      this.isPlay = !this.isPlay
      if (this.isPlay) {
        this.$refs.myVideo.play()
      } else {
        this.$refs.myVideo.pause()
      }
    },
    /**
     * 修改音量状态（有音量/静音）
     */
    changeVolumnIcon() {
      this.ismute = !this.ismute
      this.muteStatus = this.isMute ? '' : 'muted'
    },
    /**
     * 进度条更新（时间）
     */
    changeProgressByTime() {
      this.videoOpts.progress = (this.$refs.myVideo.currentTime/this.$refs.myVideo.duration*100).toFixed(1)
    },
    /**
     * 显示或隐藏控制条
     */
    toggleFooterStatus() {
      // this.isShowFooter = !this.isShowFooter
    },
    /**
     * 显示或隐藏音量条
     */
    toggleVolumeStatus () {
      this.isShowVolume = !this.isShowVolume
    },
    /**
     * 获取鼠标点击或者移动时位置的百分比
     * @param {[Number]} i 横向计算(1)或者纵向计算(2)
     * @param  {[Object]} evt 事件对象
     * @return {[Number]}     百分比
     */
    getPosPer(i, evt) {
      let len, totalLen, percent
      if (i == 1) {
        len = evt.clientX - this.left_padding
        totalLen = this.$refs.myProgress.offsetWidth
        percent = Number((len/totalLen*100).toFixed(2))
      } else if (i == 2) {
        totalLen = this.$refs.myVolume.offsetHeight
        percent = (totalLen - evt.clientY + this.videoOpts.vol_progress.scrollTop)*100/totalLen
      }
      if (percent <= 0) {
        return 0
      }
      if (percent >= 100) {
        return 100
      }
      return percent
    },
    /**
     * 根据鼠标位置，更改视频播放进度
     * @param  {Object} e 鼠标事件对象
     */
    updateVideoProgress(e) {
      const per = this.getPosPer(1, e)
      this.videoOpts.progress = per
      this.$refs.myVideo.currentTime = (this.$refs.myVideo.duration*per/100).toFixed(2)
    },
    /**
     * 根据鼠标位置，更改音量
     * @param  {Object} e 鼠标事件对象
     */
    updateVolumeProgress(e) {
      const per = this.getPosPer(2, e)
      this.videoOpts.volume = per
      this.$refs.myVideo.volume = per / 100
    },
    requestFullScreen() {
      const el = document.documentElement
      if (el.requestFullscreen) {
        el.requestFullscreen()
      } else if (el.mozRequestFullScreen) {
        el.mozRequestFullScreen()
      } else if (el.webkitRequestFullScreen) {
        el.webkitRequestFullScreen()
      }
    },
    exitFullScreen() {
      const el = document
      if (el.exitFullscreen) {
        el.exitFullscreen()
      } else if (el.mozCancelFullScreen) {
        el.mozCancelFullScreen()
      } else if (el.webkitCancelFullScreen) {
        el.webkitCancelFullScreen()
      }
    },
    // -------- 事件 event -----------
    /**
     * 视频播放时时间更新事件
     */
    timeupdate() {
      this.videoOpts.curTime = this.formatTime(Math.round(this.$refs.myVideo.currentTime))
      this.changeProgressByTime()
    },
    /**
     * 视频加载完成，可播放时的事件 
     */
    canplay() {
      this.videoOpts.curTime = this.formatTime(Math.round(this.$refs.myVideo.currentTime))
      this.videoOpts.totalTime = this.formatTime(Math.round(this.$refs.myVideo.duration))
      // this.videoOpts.volume = this.$refs.myVideo.volume*100
    },
    /**
     * 播放结束事件
     */
    timeend() {
      this.togglePlayStatus()
    },
    /**
     * 通过拖拽滑块更改视频进度的事件
     */
    changeProgressByMove(evt) {
      if (this.isPlay) {
        this.togglePlayStatus()
      }
      this.updateVideoProgress(evt)
      document.onmousemove = e => {
        this.updateVideoProgress(e)
      }
      document.onmouseup = () => {
        this.togglePlayStatus()
        document.onmousemove = document.onmouseup = null
      }
    },
    /**
     * 调节音量事件
     * @param  {Object} evt 事件对象
     */
    changeVolumeProgress(evt) {
      const rects = evt.currentTarget.getBoundingClientRect()
      this.videoOpts.vol_progress.scrollTop = rects.top
      this.updateVolumeProgress(evt)
      document.onmousemove = e => {
        this.updateVolumeProgress(e)
      }
      document.onmouseup = () => {
        document.onmousemove = document.onmouseup = null
      }
    },
    toggleFullScreen() {
      this.videoOpts.isFullScreen = !this.videoOpts.isFullScreen
      if (this.videoOpts.isFullScreen) {
        this.requestFullScreen()
      } else {
        this.exitFullScreen()
      }
    },
    error() {
      this.isError = true
    }
  }
}
</script>
<template lang="pug">
#vd-container(@mouseenter="toggleFooterStatus" @mouseleave="toggleFooterStatus" :class="{fullScreen: videoOpts.isFullScreen}")
  .vd-ele__header
  .vd-ele__body
    .vd-ele__mask(v-show="isError")
      p 视频加载错误
    video(
      :src="opts.url"
      @click="togglePlayStatus"
      @timeupdate="timeupdate"
      @ended="timeend"
      @canplay="canplay"
      @error="error"
      :muted="muteStatus"
      preload="auto"
      ref="myVideo"
      autobuffer)
  .vd-ele__footer(v-show="isShowFooter")
    button.play(:class="{pause: isPlay}" @click="togglePlayStatus")
    p.time {{videoOpts.curTime}} / {{videoOpts.totalTime}}
    .vd-ele__progress-wrap
      .vd-ele__progress(@mousedown="changeProgressByMove($event)" ref="myProgress")
        .vd-ele__progress-inner(
          :style="{'width': `${videoOpts.progress}%`}"
          ref="progress"
        )
          .vd-ele__progress-dot
    .vd-ele__settings
      p.vd-ele__settings-btn
        a(@click="toggleVolumeStatus($event)")
          i.fa(:class="[ismute?'fa-volume-off':'fa-volume-down']")
        span.vd-ele__volume(v-show="isShowVolume")
          span.vd-ele__volume-num {{videoOpts.volume}}
          span.vd-ele__volume-bar(@mousedown="changeVolumeProgress($event)" ref="myVolume")
            span.vd-ele__volume-inner(:style="{'height': `${videoOpts.volume}%`}" ref="volume")
      p.vd-ele__settings-btn
        a()
          i.fa.fa-gear
      p.vd-ele__settings-btn
        a(@click="toggleFullScreen")
          i.fa(:class="[videoOpts.isFullScreen?'fa-compress':'fa-expand']")
</template>
<style lang="less">
.full(@w: 100%, @h: 100%) {
  width: @w;
  height: @h;
}
.radius(@r: 1px) {
  border-radius: @r;
}
video::-webkit-media-controls {
  display:none !important;
}
#vd-container {
  position: relative;
  .full();
  cursor: pointer;
  .vd-ele__header {}
  .vd-ele__body {
    position: relative;
    z-index: 1;
    .full();
    .vd-ele__mask {
      position: absolute;
      top: 0;
      .full(100%, 100%);
      background-color: #d4d2d2;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 20px;
    }
    video {
      .full();
      min-height: 450px;
      object-fit: fill;
    }
  }
  .vd-ele__footer {
    position: absolute;
    display: flex;
    align-items: center;
    bottom: 0;
    padding: 0 20px;
    box-sizing: border-box;
    width: 100%;
    height: 50px;
    color: #fff;
    z-index: 2;
    button {
      margin-right: 20px;
      padding: 0;
      background-color: transparent;
      box-sizing: border-box;
      cursor: pointer;
    }
    button:focus {
      outline: none;
    }
    .play {
      height: 16px;
      border-style: solid;
      border-width: 8px 0 8px 14px;
      border-color: transparent transparent transparent #fff;
      transition: all .3s ease;
    }
    .pause {
      border-style: double;
      border-width: 0 0 0 14px;
    }
    p.time {
      margin-right: 40px;
      user-select: none;
    }
    .vd-ele__progress-wrap {
      flex: 1;
      vertical-align: middle;
      padding: 4px 0;
      .vd-ele__progress {
        position: relative;
        height: 2px;
        .radius(5px);
        background-color: rgba(0,0,0,.3);
        transition: all .3s ease;
        .vd-ele__progress-inner {
          position: relative;
          .full(0%, 100%);
          .radius(5px);
          background-color: #fff;
          // transition: all 0.1s ease;
          .vd-ele__progress-dot {
            transform: scale(0);
            transition: all .2s ease;
            position: absolute;
            .full(16px, 16px);
            top: -7px;
            right: -8px;
            background-color: lightblue;
            border-radius: 50%;
          }
        }
      }
      &:hover {
        .vd-ele__progress {
          height: 8px;
          .vd-ele__progress-dot {
            top: -3px;
            transform: scale(1);
          }
        }
      }
    }
    .vd-ele__settings {
      margin-left: 20px;
      .vd-ele__settings-btn {
        position: relative;
        display: inline-block;
        margin-left: 5px;
        .full(17px, 17px);
        .vd-ele__volume {
          display: inline-block;
          position: absolute;
          bottom: 17px;
          left: -10px;
          .full(30px, 90px);
          text-align: center;
          background-color: rgba(0,0,0,.5);
          .radius(4px);
          .vd-ele__volume-num {
            margin: 10px 0 5px;
            display: inline-block;
            font-size: 14px;
            user-select: none;
          }
          .vd-ele__volume-bar {
            position: relative;
            margin: 0 auto;
            display: block;
            .full(5px, 50px);
            background-color: rgba(0,0,0,.7);
            .radius(3px);
            .vd-ele__volume-inner {
              position: absolute;
              left: 0;
              bottom: 0;
              .full();
              .radius(3px);
              background-color: lightblue;
            }
          }
        }
      }
    }
  }
}
.fullScreen {
  position: fixed!important;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
}
</style>